home *** CD-ROM | disk | FTP | other *** search
/ PC World 2007 September / PCWorld_2007-09_cd.bin / system / ntfs / ntfsundelete.exe / {app} / pyue / ntfs.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2007-07-11  |  27KB  |  690 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. import traceback
  5. import threading
  6. import struct
  7. from fstools import *
  8.  
  9. class CNTFSError(Exception):
  10.     
  11.     def __init__(self, msg, *args, **kwargs):
  12.         Exception.__init__(self, msg, *args, **kwargs)
  13.  
  14.  
  15.  
  16. class CNTFSBootSectorError(CNTFSError):
  17.     pass
  18.  
  19.  
  20. class CNTFSMFTReferenceOverflowError(CNTFSError):
  21.     pass
  22.  
  23.  
  24. class CNTFSRelatedError(CNTFSError):
  25.     
  26.     def __init__(self, msg, related_exception):
  27.         CNTFSError.__init__(self, msg + ' (Reason: %s) ' % str(related_exception))
  28.         self.related_exception = related_exception
  29.  
  30.  
  31.  
  32. def extent_map_from_ntfs_extents(e):
  33.     '''
  34.         convert fstools ntfs extent list
  35.         to space.ExtentMap object
  36.     '''
  37.     
  38.     try:
  39.         R = CExtentList()
  40.         for i in xrange(len(e)):
  41.             item = e.get_extent(i)
  42.             R.add_mapping(item.vcn, item.length, item.lcn)
  43.         
  44.         return R
  45.     except Exception:
  46.         Value = None
  47.         raise CNTFSRelatedError('Cannot convert NTFS extent map', Value)
  48.  
  49.  
  50.  
  51. def load_attr_list(linear_space):
  52.     '''
  53.         read ATTRIBUTE_LIST object from
  54.         linear space
  55.     '''
  56.     if linear_space.size < 256 * 1024:
  57.         raw_data = linear_space.read_data(0, linear_space.size)
  58.         
  59.         try:
  60.             return new_ntfs_attrlist_object(raw_data)
  61.         raise CNTFSError('Invalid AT_ATTRIBUTE_LIST attribute')
  62.  
  63.     else:
  64.         raise CNTFSError('Invalid attribute list size')
  65.  
  66.  
  67. class CNTFSDataStream(CLinearSpace):
  68.     '''
  69.         Named linear space class
  70.     '''
  71.     
  72.     def __init__(self, name, linear_space):
  73.         '''
  74.             __init__(self, name, linear_space)
  75.         '''
  76.         self._CNTFSDataStream__name = name
  77.         self._CNTFSDataStream__linear_space = linear_space
  78.  
  79.     
  80.     def get_size(self):
  81.         return self._CNTFSDataStream__linear_space.get_size()
  82.  
  83.     
  84.     def _read_data(self, start_pos, count, buffer_size):
  85.         return self._CNTFSDataStream__linear_space._read_data(start_pos, count, buffer_size)
  86.  
  87.     name = property((lambda self: self._CNTFSDataStream__name))
  88.  
  89.  
  90. class CNTFSIndex:
  91.     '''
  92.         NTFS index container.
  93.  
  94.         Attributes:
  95.  
  96.         entries         - a list of entries in index
  97.         type            - type of indexed entries
  98.         collation_rule  - collation rule
  99.         index_block_size - size of NTFS index block
  100.     '''
  101.     
  102.     def __init__(self, index_block_size = None, collation_rule = None, type = None):
  103.         '''__init__(index_block_size=None, collation_rule=None, type=None)'''
  104.         self._CNTFSIndex__entries = []
  105.         self._CNTFSIndex__type = type
  106.         self._CNTFSIndex__collation_rule = collation_rule
  107.         self._CNTFSIndex__index_block_size = index_block_size
  108.         self._CNTFSIndex__index_blocks = []
  109.  
  110.     
  111.     def __len__(self):
  112.         return len(self._CNTFSIndex__entries)
  113.  
  114.     
  115.     def __getitem__(self, index):
  116.         return self._CNTFSIndex__entries[index]
  117.  
  118.     entries = property((lambda self: self._CNTFSIndex__entries))
  119.     type = property((lambda self: self._CNTFSIndex__type))
  120.     collation_rule = property((lambda self: self._CNTFSIndex__collation_rule))
  121.     index_block_size = property((lambda self: self._CNTFSIndex__index_block_size))
  122.     index_blocks = property((lambda self: self._CNTFSIndex__index_blocks))
  123.  
  124.  
  125. class CNTFSFile:
  126.     
  127.     def __init__(self, volume, mft_ref):
  128.         self._CNTFSFile__volume = volume
  129.         self._CNTFSFile__mft_ref = mft_ref
  130.  
  131.     
  132.     def open(self):
  133.         
  134.         try:
  135.             volume = self._CNTFSFile__volume
  136.             self._CNTFSFile__data_streams = { }
  137.             self._CNTFSFile__file_names = { }
  138.             self._CNTFSFile__win32_file_names = { }
  139.             self._CNTFSFile__ntfs_attributes = []
  140.             self._CNTFSFile__mft_records = []
  141.             self._CNTFSFile__mft_refs = [
  142.                 self._CNTFSFile__mft_ref]
  143.             self._CNTFSFile__ntfs_attributes_by_type = { }
  144.             self._CNTFSFile__mft_record = mft_record = volume.MFT.load_mft_record(self._CNTFSFile__mft_ref)
  145.             self._CNTFSFile__is_directory = mft_record.get_flags() & MFT_RECORD_IS_DIRECTORY
  146.             self._CNTFSFile__is_deleted = mft_record.get_flags() & MFT_RECORD_IN_USE == 0
  147.             self._CNTFSFile__index_allocations = []
  148.             self._CNTFSFile__index_roots = []
  149.             self._CNTFSFile__std_infos = []
  150.             self._CNTFSFile__default_data_stream_size = 0x0L
  151.             self._init_with_mft_entry(mft_record)
  152.         except CNTFSError:
  153.             Value = None
  154.             raise CNTFSRelatedError('Cannot open file %s' % hex(self._CNTFSFile__mft_ref), Value)
  155.  
  156.  
  157.     
  158.     def open_if_base(self):
  159.         
  160.         try:
  161.             volume = self._CNTFSFile__volume
  162.             self._CNTFSFile__data_streams = { }
  163.             self._CNTFSFile__file_names = { }
  164.             self._CNTFSFile__win32_file_names = { }
  165.             self._CNTFSFile__ntfs_attributes = []
  166.             self._CNTFSFile__mft_records = []
  167.             self._CNTFSFile__mft_refs = [
  168.                 self._CNTFSFile__mft_ref]
  169.             self._CNTFSFile__ntfs_attributes_by_type = { }
  170.             self._CNTFSFile__mft_record = mft_record = volume.MFT.load_mft_record(self._CNTFSFile__mft_ref)
  171.             if not self.is_base_entry:
  172.                 raise CNTFSError('Cannot open file on non-base entry %s' % hex(self._CNTFSFile__mft_ref))
  173.             
  174.             self._CNTFSFile__is_directory = mft_record.get_flags() & MFT_RECORD_IS_DIRECTORY
  175.             self._CNTFSFile__is_deleted = mft_record.get_flags() & MFT_RECORD_IN_USE == 0
  176.             self._CNTFSFile__index_allocations = []
  177.             self._CNTFSFile__index_roots = []
  178.             self._CNTFSFile__std_infos = []
  179.             self._CNTFSFile__default_data_stream_size = 0x0L
  180.             self._init_with_mft_entry(mft_record)
  181.         except CNTFSError:
  182.             Value = None
  183.             raise CNTFSRelatedError('Cannot open file %s' % hex(self._CNTFSFile__mft_ref), Value)
  184.  
  185.  
  186.     
  187.     def has_file_name(self, file_name):
  188.         return self._CNTFSFile__file_names.has_key(file_name)
  189.  
  190.     
  191.     def read_indexes(self):
  192.         volume = self._CNTFSFile__volume
  193.         indexes = { }
  194.         for index_root in self._CNTFSFile__index_roots:
  195.             
  196.             try:
  197.                 index_root_object = new_ntfs_indexroot_object(index_root.get_content())
  198.                 name = index_root.get_name()
  199.                 index_block_size = index_root_object.get_index_block_size()
  200.                 collation_rule = index_root_object.get_collation_rule()
  201.                 type = index_root_object.get_type()
  202.                 index = CNTFSIndex(index_block_size, collation_rule, type)
  203.                 
  204.                 trans = lambda x: (x, None)
  205.                 indexes[name] = index
  206.                 if type == AT_FILE_NAME:
  207.                     
  208.                     trans = lambda x: (x, new_ntfs_filename_object(x.get_key()))
  209.                 
  210.                 for i in xrange(index_root_object.get_count()):
  211.                     index.entries.append(trans(index_root_object.get_entry(i)))
  212.             continue
  213.             raise CNTFSError('Invalid INDEX_ROOT attribute')
  214.             continue
  215.  
  216.         
  217.         for attr in self._CNTFSFile__index_allocations:
  218.             index = None
  219.             index_block_size = self.volume.index_record_size
  220.             
  221.             trans = lambda x: (x, None)
  222.             if indexes.has_key(name):
  223.                 index = indexes[name]
  224.                 index_block_size = index.index_block_size
  225.                 if index.type != None and index.type == AT_FILE_NAME:
  226.                     
  227.                     trans = lambda x: (x, new_ntfs_filename_object(x.get_key()))
  228.                 
  229.             else:
  230.                 index = CNTFSIndex(None, index_block_size)
  231.                 indexes[name] = index
  232.             pos = 0
  233.             ls = attr.linear_space
  234.             while pos < ls.size:
  235.                 raw_data = ls.read_data(pos, index_block_size)
  236.                 
  237.                 try:
  238.                     index_allocation = new_ntfs_indexblock_object(raw_data, volume.disk.sector_size)
  239.                     index.index_blocks.append(index_allocation)
  240.                 except Exception:
  241.                     Value = None
  242.                     raise CNTFSError('Invalid INDEX_BLOCK')
  243.  
  244.                 
  245.                 try:
  246.                     for i in xrange(index_allocation.get_count()):
  247.                         index.entries.append(trans(index_allocation.get_entry(i)))
  248.                 except:
  249.                     raise CNTFSError('Invalid index entry')
  250.  
  251.                 pos += index_block_size
  252.         
  253.         return indexes
  254.  
  255.     
  256.     def _init_with_mft_entry(self, mft_record):
  257.         volume = self._CNTFSFile__volume
  258.         abt = self._CNTFSFile__ntfs_attributes_by_type
  259.         self._CNTFSFile__mft_records.append(mft_record)
  260.         for i in xrange(mft_record.get_rattr_count()):
  261.             attr = mft_record.get_rattribute(i)
  262.             self._CNTFSFile__ntfs_attributes.append(attr)
  263.             tp = attr.get_type()
  264.             if abt.has_key(tp):
  265.                 abt[tp].append(attr)
  266.             else:
  267.                 abt[tp] = [
  268.                     attr]
  269.             if attr.get_type() == AT_FILE_NAME:
  270.                 
  271.                 try:
  272.                     content = attr.get_content()
  273.                     file_name_object = new_ntfs_filename_object(content)
  274.                     fname = file_name_object.get_file_name()
  275.                     self._CNTFSFile__file_names[fname] = file_name_object
  276.                     if file_name_object.get_file_name_type() & FILE_NAME_WIN32:
  277.                         self._CNTFSFile__win32_file_names[fname] = file_name_object
  278.                 except Exception:
  279.                     Value = None
  280.                     raise CNTFSRelatedError('Cannot obtain AT_FILE_NAME attribute', Value)
  281.                 except:
  282.                     None<EXCEPTION MATCH>Exception
  283.                 
  284.  
  285.             None<EXCEPTION MATCH>Exception
  286.             if attr.get_type() == AT_DATA:
  287.                 content = attr.get_content()
  288.                 name = attr.get_name()
  289.                 ls = CreateCRefBufferSpace(content)
  290.                 if name == '':
  291.                     self._CNTFSFile__default_data_stream_size = ls.get_size()
  292.                 
  293.                 self._CNTFSFile__data_streams[name] = CNTFSDataStream(name, ls)
  294.                 continue
  295.             None if attr.get_type() == AT_ATTRIBUTE_LIST else len(content) > 48
  296.         
  297.         for i in xrange(mft_record.get_nattr_count()):
  298.             attr = mft_record.get_nattribute(i)
  299.             self._CNTFSFile__ntfs_attributes.append(attr)
  300.             tp = attr.get_type()
  301.             if abt.has_key(tp):
  302.                 abt[tp].append(attr)
  303.             else:
  304.                 abt[tp] = [
  305.                     attr]
  306.             extents = extent_map_from_ntfs_extents(attr.get_extents())
  307.             cs = None
  308.             if attr.get_flags() & ATTR_IS_COMPRESSED and attr.get_compression_unit():
  309.                 cs = CreateCNTFSCompressedClusterSpace(volume.cluster_space, attr.get_compression_unit())
  310.             else:
  311.                 cs = CreateCMappedClusterSpace(volume.cluster_space)
  312.             cs.get_extents().extend(extents)
  313.             ls = CreateCClusterLinearizer(cs, attr.get_data_size(), 0)
  314.             if attr.get_type() == AT_DATA:
  315.                 name = attr.get_name()
  316.                 if self._CNTFSFile__data_streams.has_key(name):
  317.                     self._CNTFSFile__data_streams[name].extents.extend(extents)
  318.                 else:
  319.                     self._CNTFSFile__data_streams[name] = ds = CNTFSDataStream(name, ls)
  320.                     ds.extents = cs.get_extents()
  321.                 if name == '':
  322.                     self._CNTFSFile__default_data_stream_size = self._CNTFSFile__data_streams[''].size
  323.                 
  324.             name == ''
  325.             if attr.get_type() == AT_ATTRIBUTE_LIST:
  326.                 attr_list = load_attr_list(ls)
  327.                 for attr_e in attr_list:
  328.                     mft_ref = attr_e.get_mft_reference() & 0xFFFFFFFFFFFFL
  329.                     self._CNTFSFile__mft_refs.append(mft_ref)
  330.                     if mft_ref != self._CNTFSFile__mft_ref:
  331.                         rec = volume.MFT.load_mft_record(mft_ref)
  332.                         self._init_with_mft_entry(rec)
  333.                         continue
  334.                 
  335.         
  336.  
  337.     
  338.     def get_standard_info(self):
  339.         si = self.std_infos
  340.         if len(si) > 0:
  341.             si = si[0]
  342.             return (si.get_creation_time(), si.get_last_data_change_time(), si.get_last_access_time(), si.get_last_mft_change_time(), si.get_file_attributes())
  343.         else:
  344.             return (0x0L, 0x0L, 0x0L, 0x0L, 0x0L)
  345.  
  346.     mft_ref = property((lambda self: self._CNTFSFile__mft_ref))
  347.     base_mft_ref = property((lambda self: self._CNTFSFile__mft_record.get_base_mft_record() & 0xFFFFFFFFFFFFL))
  348.     is_base_entry = property((lambda self: self.base_mft_ref == 0))
  349.     data_streams = property((lambda self: self._CNTFSFile__data_streams))
  350.     data_stream_list = property((lambda self: self._CNTFSFile__data_streams.values()))
  351.     data_stream_count = property((lambda self: len(self._CNTFSFile__data_streams)))
  352.     file_names = property((lambda self: self._CNTFSFile__file_names))
  353.     file_name_list = property((lambda self: self._CNTFSFile__file_names.values()))
  354.     file_name_count = property((lambda self: len(self._CNTFSFile__file_names)))
  355.     is_directory = property((lambda self: self._CNTFSFile__is_directory))
  356.     is_deleted = property((lambda self: self._CNTFSFile__is_deleted))
  357.     volume = property((lambda self: self._CNTFSFile__volume))
  358.     ntfs_atributes = property((lambda self: self._CNTFSFile__ntfs_attributes))
  359.     ntfs_attributes_by_type = property((lambda self: self._CNTFSFile__ntfs_attributes_by_type))
  360.     mft_records = property((lambda self: self._CNTFSFile__mft_records[:]))
  361.     mft_refs = property((lambda self: self._CNTFSFile__mft_refs))
  362.     win32_file_names = property((lambda self: self._CNTFSFile__win32_file_names))
  363.     win32_file_name_list = property((lambda self: self._CNTFSFile__win32_file_names.values()))
  364.     win32_file_name_count = property((lambda self: len(self._CNTFSFile__win32_file_names)))
  365.     mft_record = property((lambda self: self._CNTFSFile__mft_record))
  366.     std_infos = property((lambda self: self._CNTFSFile__std_infos))
  367.     default_data_stream_size = property((lambda self: self._CNTFSFile__default_data_stream_size))
  368.  
  369.  
  370. class CNTFSMFT(CNTFSFile):
  371.     '''
  372.         class for $MFT file
  373.     '''
  374.     
  375.     def __init__(self, volume):
  376.         CNTFSFile.__init__(self, volume, 0)
  377.  
  378.     
  379.     def open(self):
  380.         CNTFSFile.open(self)
  381.         self._CNTFSMFT__main_stream = self.data_streams['']
  382.  
  383.     
  384.     def load_mft_record(self, mft_ref):
  385.         if mft_ref < 0:
  386.             raise CNTFSMFTReferenceOverflowError('Invalid MFT reference access')
  387.         
  388.         v = self.volume
  389.         mr = v.mft_record_size
  390.         if mft_ref < 16:
  391.             raw_data = v.linear_space.read_data(v.mft_lcn * v.cluster_size + mr * mft_ref, mr)
  392.             return parse_mft_record(raw_data, v.disk.sector_size)
  393.         elif mft_ref >= self.mft_record_count:
  394.             raise CNTFSMFTReferenceOverflowError('Invalid MFT reference access')
  395.         
  396.         raw_data = self.data_streams[''].read_data(mr * mft_ref, mr)
  397.         
  398.         try:
  399.             return parse_mft_record(raw_data, v.disk.sector_size)
  400.         except:
  401.             raise CNTFSError('Invalid MFT entry at %s' % hex(mft_ref))
  402.  
  403.  
  404.     mft_record_size = property((lambda self: self.volume.mft_record_size))
  405.     mft_record_count = property((lambda self: self.data_streams[''].size / self.mft_record_size))
  406.  
  407.  
  408. class CNTFSVolume:
  409.     
  410.     def __init__(self, disk, start_sector, sector_count, related_partition = None):
  411.         self._CNTFSVolume__start_sector = start_sector
  412.         self._CNTFSVolume__sector_count = sector_count
  413.         self._CNTFSVolume__related_partition = related_partition
  414.         self._CNTFSVolume__disk = disk
  415.         self._CNTFSVolume__lck = threading.Lock()
  416.  
  417.     
  418.     def open_file(self, mft_ref):
  419.         self._CNTFSVolume__lck.acquire()
  420.         
  421.         try:
  422.             file = CNTFSFile(self, mft_ref)
  423.             file.open()
  424.         finally:
  425.             self._CNTFSVolume__lck.release()
  426.  
  427.         return file
  428.  
  429.     
  430.     def open_file_if_base(self, mft_ref):
  431.         self._CNTFSVolume__lck.acquire()
  432.         
  433.         try:
  434.             file = CNTFSFile(self, mft_ref)
  435.             file.open_if_base()
  436.         finally:
  437.             self._CNTFSVolume__lck.release()
  438.  
  439.         return file
  440.  
  441.     
  442.     def initialize(self):
  443.         '''
  444.         initialize(self)
  445.         Just initialize CNTFSVolume object. Result is None
  446.         or any exception, if has any errors
  447.         '''
  448.         disk = self.disk
  449.         self._CNTFSVolume__boot_sector = boot_sector = ntfs_bootsector_from(disk.read_sectors(self.start_sector, 1))
  450.         if boot_sector.end_of_sector_marker != 43605:
  451.             raise CNTFSBootSectorError('Invalid boot sector marker')
  452.         
  453.         if boot_sector.oem_id != 0x202020205346544EL:
  454.             raise CNTFSBootSectorError('Invalid OEM ID of NTFS boot sector')
  455.         
  456.         if boot_sector.clusters_per_mft_record == 0:
  457.             raise CNTFSBootSectorError('Invalid MFT record size')
  458.         
  459.         if boot_sector.clusters_per_index_record == 0:
  460.             raise CNTFSBootSectorError('Invalid INDX record size')
  461.         
  462.         cluster_size = boot_sector.bpb.bytes_per_sector * boot_sector.bpb.sectors_per_cluster
  463.         mft_record_size = 0
  464.         index_record_size = 0
  465.         if boot_sector.clusters_per_mft_record > 0:
  466.             mft_record_size = boot_sector.clusters_per_mft_record * cluster_size
  467.         else:
  468.             mft_record_size = 1 << -(boot_sector.clusters_per_mft_record)
  469.         if boot_sector.clusters_per_index_record > 0:
  470.             index_record_size = boot_sector.clusters_per_index_record * cluster_size
  471.         else:
  472.             index_record_size = 1 << -(boot_sector.clusters_per_index_record)
  473.         self._CNTFSVolume__cluster_space = cluster_space = CreateCDiskClusterizer(disk, boot_sector.bpb.sectors_per_cluster, self.sector_count, self.start_sector)
  474.         self._CNTFSVolume__linear_space = linear_space = CreateCClusterLinearizer(disk, self.sector_count * disk.sector_size, self.start_sector)
  475.         self._CNTFSVolume__mft_lcn = mft_lcn = boot_sector.mft_lcn
  476.         self._CNTFSVolume__mftmirr_lcn = mft_mirr_lcn = boot_sector.mftmirr_lcn
  477.         self._CNTFSVolume__cluster_size = cluster_size
  478.         self._CNTFSVolume__mft_record_size = mft_record_size
  479.         self._CNTFSVolume__index_record_size = index_record_size
  480.         self._CNTFSVolume__volume_serial_number = boot_sector.volume_serial_number
  481.         self._CNTFSVolume__number_of_sectors = boot_sector.number_of_sectors
  482.         self._CNTFSVolume__MFT = CNTFSMFT(self)
  483.         self._CNTFSVolume__MFT.open()
  484.  
  485.     
  486.     def mft_ref_for_path(self, full_file_name_and_path):
  487.         '''
  488.         mft_ref_for_path(self, full_file_name_and_path)
  489.         returns mft reference for given existant path, or -1 if 
  490.         path cannot be resolved.
  491.         '''
  492.         current_folder = FILE_root
  493.         items = filter((lambda x: x != u''), unicode(full_file_name_and_path).split('\\'))
  494.         idx = 0
  495.         while True:
  496.             folder = CNTFSFile(self, current_folder)
  497.             folder.open()
  498.             indexes = folder.read_indexes()
  499.             if idx == len(items):
  500.                 if folder.has_file_name(items[idx - 1]):
  501.                     return current_folder
  502.                 else:
  503.                     return -1
  504.             
  505.             if not (folder.is_directory) or not indexes.has_key(u'$I30'):
  506.                 return -1
  507.             
  508.             index = indexes[u'$I30']
  509.             Found = False
  510.             for entry, related_object in index.entries:
  511.                 if isinstance(related_object, CNTFSFileNameObject):
  512.                     if related_object.get_file_name() == items[idx]:
  513.                         current_folder = entry.get_indexed_file() & 0xFFFFFFFFFFFFL
  514.                         Found = True
  515.                         idx += 1
  516.                         break
  517.                     
  518.                 related_object.get_file_name() == items[idx]
  519.             
  520.             if not Found:
  521.                 return -1
  522.                 continue
  523.  
  524.     
  525.     def path_for_mft_ref(self, mft_ref):
  526.         '''
  527.         path_for_mft_ref(self, mft_ref)
  528.         returns path for mft reference if possible,
  529.         or None, if path cannot be built.
  530.         '''
  531.         R = ''
  532.         f = CNTFSFile(self, mft_ref)
  533.         f.open()
  534.         while mft_ref != FILE_root:
  535.             if len(f.win32_file_names):
  536.                 file_name = f.win32_file_names.keys()[0]
  537.             elif len(f.file_names):
  538.                 file_name = f.file_names.keys()[0]
  539.             else:
  540.                 return None
  541.             mft_ref = f.file_names[file_name].get_parent_directory() & 0xFFFFFFFFFFFFL
  542.             f = CNTFSFile(self, mft_ref)
  543.             f.open()
  544.             if not f.is_directory:
  545.                 return None
  546.                 continue
  547.             R = file_name + '\\' + R
  548.         return '\\' + R
  549.  
  550.     
  551.     def read_attr_defs(self):
  552.         '''
  553.         read_attr_defs(self)
  554.         returns a list of attr_def entries
  555.         in $AttrDef file, or exception, if there
  556.         errors.
  557.         '''
  558.         file = CNTFSFile(self, FILE_AttrDef)
  559.         file.open()
  560.         if not file.data_streams.has_key(''):
  561.             raise CNTFSError('$AttrDef file has no default data stream')
  562.         
  563.         ds = file.data_streams['']
  564.         sz = ds.size
  565.         if sz % 160 == 0:
  566.             count = sz / 160
  567.             struc = '=' + '160s' * count
  568.             data = struct.unpack(struc, ds.read_data(0, sz))
  569.             
  570.             try:
  571.                 return map((lambda x: new_ntfs_attrdef_object(x)), data)
  572.             raise CNTFSError('Invalid ATTR_DEF records in $AttrDef file')
  573.  
  574.         else:
  575.             raise CNTFSError('Invalid $AttrDef data stream size')
  576.  
  577.     
  578.     def read_volume_information(self):
  579.         '''
  580.         read_volume_information(self)
  581.         returns volume_information object
  582.         from $Volume file, or raises an
  583.         exception, if errors.
  584.         '''
  585.         file = CNTFSFile(self, FILE_Volume)
  586.         file.open()
  587.         if file.ntfs_attributes_by_type.has_key(AT_VOLUME_INFORMATION):
  588.             attr = file.ntfs_attributes_by_type[AT_VOLUME_INFORMATION][0]
  589.             
  590.             try:
  591.                 return new_ntfs_volumeinformation_object(attr.get_content())
  592.             raise CNTFSError('Invalid AT_VOLUME_INFORMATION attribute value in file $Volume')
  593.  
  594.         else:
  595.             raise CNTFSError('File $Volume has no AT_VOLUME_INFORMATION attribute')
  596.  
  597.     cluster_space = property((lambda self: self._CNTFSVolume__cluster_space))
  598.     linear_space = property((lambda self: self._CNTFSVolume__linear_space))
  599.     mft_lcn = property((lambda self: self._CNTFSVolume__mft_lcn))
  600.     mftmirr_lcn = property((lambda self: self._CNTFSVolume__mftmirr_lcn))
  601.     cluster_size = property((lambda self: self._CNTFSVolume__cluster_size))
  602.     mft_record_size = property((lambda self: self._CNTFSVolume__mft_record_size))
  603.     index_record_size = property((lambda self: self._CNTFSVolume__index_record_size))
  604.     volume_serial_number = property((lambda self: self._CNTFSVolume__volume_serial_number))
  605.     number_of_sectors = property((lambda self: self._CNTFSVolume__number_of_sectors))
  606.     MFT = property((lambda self: self._CNTFSVolume__MFT))
  607.     disk = property((lambda self: self._CNTFSVolume__disk))
  608.     related_partition = property((lambda self: self._CNTFSVolume__related_partition))
  609.     start_sector = property((lambda self: self._CNTFSVolume__start_sector))
  610.     sector_count = property((lambda self: self._CNTFSVolume__sector_count))
  611.  
  612.  
  613. def test():
  614.     '''
  615.     import boot
  616.     import partition as prt
  617.     import validate
  618.     import time
  619.     import random
  620.               
  621.                 
  622.  
  623.  
  624.     def get_logical_partitions(prt_tree):
  625.         R = []
  626.         for partition in prt_tree:
  627.             if isinstance(partition, prt.ExtendedPartition):
  628.                 R.extend(get_logical_partitions(partition.partitions))
  629.             else:
  630.                 R.append(partition)
  631.         return R
  632.  
  633.  
  634.     def process(disk, partition):
  635.         volume = CNTFSVolume(disk, partition.start_sector, partition.sector_count)
  636.         volume.initialize()
  637.         R = []
  638.  
  639.         T = time.time()
  640.         for i in xrange(volume.MFT.mft_record_count):
  641.             try:
  642.                 file = CNTFSFile(volume, i)
  643.                 file.open()
  644.                 #if file.is_deleted:
  645.                 #    R.append(file)
  646.                 #volume.MFT.load_mft_record(i)
  647.                 #print file.file_names.keys(), file.data_streams.keys()
  648.                 if i % 0x100 == 0:
  649.                     print "passed: ", hex(i), disk.get_cache_hits(), disk.get_cache_miss(), "\r", 
  650.             except Exception, Value:
  651.                 print "Error at ", hex(i), Value, hex(volume.MFT.mft_record_count)
  652.         print "Time: ", time.time() - T, "Items: ", volume.MFT.mft_record_count
  653.  
  654.     
  655.     try:        
  656.         logger = validate.StdioLogger()
  657.         disk = CreateCCachedDisk(CreateCOSDisk(u"\\\\.\\PhysicalDrive1"), 7, 64)
  658.         #disk = CreateCCachedDisk(CreateCOSDisk(u"F:\\vmw\\winxp\\Windows XP Professional-flat.vmdk"), 7, 64)
  659.         partitions = get_logical_partitions(prt.PartitionValidator(logger).validate(disk))
  660.         for partition in partitions:
  661.             if partition.partition_type == boot.PARTITION_IFS:
  662.                 print "FOUND NTFS at: ", partition.start_sector, partition.sector_count
  663.                 process(disk, partition)
  664.                 raw_input()
  665.     except Exception, Value:
  666.         print "
  667.  
  668. ***Error : ", Value, "****
  669. "
  670.         traceback.print_exc()
  671.         raw_input()
  672.     '''
  673.     
  674.     def on_prog(drive_name, volume, pos, percent):
  675.         print 'Progreess: ', percent, '\r',
  676.  
  677.     
  678.     def on_deleted_file(drive_name, mft_ref, file):
  679.         pass
  680.  
  681.     disk = CreateCCachedDisk(CreateCOSDisk(u'\\\\.\\X:'), 7, 64)
  682.     volume = CNTFSVolume(disk, 0, disk.sector_count)
  683.     volume.initialize()
  684.     F = volume.open_file(2)
  685.     print F.file_names.keys()
  686.  
  687. if __name__ == '__main__':
  688.     test()
  689.  
  690.